//
// Created by wlk12 on 2024/3/1.
//
#include <iostream>
#include <memory>

enum Type
{
    A, B
};

class Obj
{
public:
    Obj() = default;
    virtual ~Obj() = default;
    virtual void fun() = 0;
};

class ObjA : public Obj
{
public:
    ObjA() = default;
    ~ObjA() override = default;

    void fun() override
    {
        std::cout << "ObjA" << std::endl;
    }
private:
    int a{};
};

class ObjB : public Obj
{
public:
    ObjB() = default;
    ~ObjB() override = default;

    void fun() override
    {
        std::cout << "ObjB" << std::endl;
    }

private:
    int b{};
};

class SimpleFactory
{
public:
    Obj* create(Type type)
    {
        switch (type)
        {
        case Type::A:
            return new ObjA;
        case Type::B:
            return new ObjB;
        default:
            break;
        }
        return nullptr;
    }
};

class Factory
{
public:
    Factory() = default;
    virtual ~Factory() = default;
    virtual Obj* create() = 0;
};

class FactoryA : public Factory
{
public:

    ObjA* create() override
    {
        return new ObjA;
    }
};

class FactoryB : public Factory
{
public:

    ObjB* create() override
    {
        return new ObjB;
    }
};


int main()
{
    {
        SimpleFactory factory1;
        auto ta = factory1.create(Type::A);
        auto tb = factory1.create(Type::B);
        ta->fun();
        tb->fun();
        delete ta;
        delete tb;
    }


    std::cout << "-------abstract Factory-------" << std::endl;
    {
        std::unique_ptr<Factory> factory;
        factory = std::make_unique<FactoryA>();
        auto a = factory->create();
        a->fun();
        delete a;

        factory = std::make_unique<FactoryB>();
        auto b = factory->create();
        b->fun();
        delete b;
    }

    return 0;
}